package com.whfc.base.manager.impl;

import com.alibaba.fastjson.JSON;
import com.whfc.base.dao.AppWarnFreqConfigMapper;
import com.whfc.base.dto.AppWarnFreqConfigDTO;
import com.whfc.base.dto.AlarmCacheDTO;
import com.whfc.base.entity.AppWarnFreqConfig;
import com.whfc.base.enums.AppWarnConfigType;
import com.whfc.base.manager.AppAlarmConfigManager;
import com.whfc.base.redis.AlarmRecordRedisDao;
import com.whfc.base.redis.WarnConfigRedisDao;
import com.whfc.common.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Random;

/**
 * @author sun_guodong
 * @description
 * @date 2021-01-08
 */
@Service
public class AppAlarmConfigManagerImpl implements AppAlarmConfigManager {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AppWarnFreqConfigMapper appWarnFreqConfigMapper;

    @Autowired
    private WarnConfigRedisDao warnConfigRedisDao;

    @Autowired
    private AlarmRecordRedisDao alarmRecordRedisDao;

    /**
     * 默认值
     */
    private static final Integer DEFAULT_FREQUENCY_LIMIT_DAY = 96;
    private static final Integer DEFAULT_FREQUENCY_LIMIT_HOUR = 4;
    private static final Integer DEFAULT_FREQUENCY_LIMIT_INTERVAL = 15;


    @Override
    public boolean checkAlarmFrequency(Integer deptId, Integer moduleType, Integer ruleType, String objectId, Date triggerTime) {
        boolean flag;
        // 检测该项目的报警频率
        AlarmCacheDTO alarmRecord3 = alarmRecordRedisDao.getAlarmRecord(moduleType, deptId);
        AppWarnFreqConfigDTO alarmConfig3 = this.getAlarmConfig(deptId, moduleType, AppWarnConfigType.MODULE_DEPT.value(), null);
        boolean flag3 = this.checkWarnFrequency(triggerTime, alarmRecord3, alarmConfig3);
        if (!flag3) {
            logger.info("flag3 报警频率限制：{}", JSON.toJSONString(alarmConfig3));
            return false;
        }

        // 检测该项目该报警类型报警频率
        AlarmCacheDTO alarmRecord4 = alarmRecordRedisDao.getAlarmRecord(moduleType, deptId, ruleType);
        AppWarnFreqConfigDTO alarmConfig4 = this.getAlarmConfig(deptId, moduleType, AppWarnConfigType.MODULE_DEPT_RULE.value(), ruleType);
        boolean flag4 = this.checkWarnFrequency(triggerTime, alarmRecord4, alarmConfig4);
        if (!flag4) {
            logger.info("flag4 报警频率限制：{}", JSON.toJSONString(alarmConfig4));
            return false;
        }

        // 检测该设备报警频率
//        AlarmCacheDTO alarmRecord2 = alarmRecordRedisDao.getAlarmRecord(moduleType, objectId);
//        AppWarnFreqConfigDTO alarmConfig2 = this.getAlarmConfig(deptId, moduleType, AppWarnConfigType.MODULE_OBJ.value(),null);
//        boolean flag2 = this.checkWarnFrequency(triggerTime, alarmRecord2, alarmConfig2);
//        if (!flag2) {
//            return false;
//        }

        // 检测该设备该报警类型的报警频率
        AlarmCacheDTO alarmRecord1 = alarmRecordRedisDao.getAlarmRecord(moduleType, ruleType, objectId);
        AppWarnFreqConfigDTO alarmConfig1 = this.getAlarmConfig(deptId, moduleType, AppWarnConfigType.MODULE_RULE_OBJ.value(), ruleType);
        boolean flag1 = this.checkWarnFrequency(triggerTime, alarmRecord1, alarmConfig1);

        flag = flag1 && flag3 && flag4;
        if (flag) {
            // 统计报警次数
            alarmRecordRedisDao.setAlarmRecord(moduleType, ruleType, objectId, alarmRecord1);
            //  alarmRecordRedisDao.setAlarmRecord(moduleType, objectId, alarmRecord2);
            alarmRecordRedisDao.setAlarmRecord(moduleType, deptId, alarmRecord3);
            alarmRecordRedisDao.setAlarmRecord(moduleType, deptId, ruleType, alarmRecord4);
        }
        return flag;
    }


    /**
     * 检测报警频率
     *
     * @param triggerTime
     * @param alarmRecord
     * @param warnFreqConfig
     * @return
     */
    private boolean checkWarnFrequency(Date triggerTime, AlarmCacheDTO alarmRecord, AppWarnFreqConfigDTO warnFreqConfig) {
        if (alarmRecord.getTime() == null) {
            alarmRecord.setHourWarnNo(1);
            alarmRecord.setTime(triggerTime);
            alarmRecord.setDayWarnNo(1);
            return true;
        } else {
            Integer dayWarnNo = alarmRecord.getDayWarnNo();
            Integer hourWarnNo = alarmRecord.getHourWarnNo();
            Date time = alarmRecord.getTime();

            Integer frequencyLimitHour;
            Integer frequencyLimitInterval;
            Integer frequencyLimitDay;
            if (warnFreqConfig.getFrequencyLimitInterval() == -1) {
                // 不限制
                return true;
            } else if (warnFreqConfig.getFrequencyLimitInterval() == 0) {
                // 禁止
                return false;
            } else {
                frequencyLimitDay = warnFreqConfig.getFrequencyLimitDay();
                frequencyLimitHour = warnFreqConfig.getFrequencyLimitHour();
                frequencyLimitInterval = warnFreqConfig.getFrequencyLimitInterval();
            }
            // 增加时间间隔浮动
            Random random = new Random();
            frequencyLimitInterval = frequencyLimitInterval + random.nextInt(60);

            // 超出一个小时，重新设置一个小时内的报警次数
            if (!DateUtil.getHourStart(time).equals(DateUtil.getHourStart(triggerTime))) {
                hourWarnNo = 0;
            }

            if (DateUtil.addMinutes(time, frequencyLimitInterval).before(triggerTime) && hourWarnNo < frequencyLimitHour && dayWarnNo < frequencyLimitDay) {
                alarmRecord.setDayWarnNo(dayWarnNo + 1);
                alarmRecord.setTime(triggerTime);
                alarmRecord.setHourWarnNo(hourWarnNo + 1);
                return true;
            }
            return false;
        }
    }


    /**
     * 获取报警频率设置
     *
     * @param deptId
     * @param warnModuleType
     * @param type
     * @return
     */
    private AppWarnFreqConfigDTO getAlarmConfig(Integer deptId, Integer warnModuleType, Integer type, Integer ruleType) {
        AppWarnFreqConfigDTO warnConfigDTO = warnConfigRedisDao.getWarnConfig(deptId, warnModuleType, type, ruleType);
        if (warnConfigDTO == null) {
            AppWarnFreqConfig warnFreqConfig = appWarnFreqConfigMapper.selectByDeptIdAndModuleType(deptId, warnModuleType, type, ruleType);
            if (warnFreqConfig == null) {
                warnFreqConfig = new AppWarnFreqConfig();
                // 设置默认值
                warnFreqConfig.setFrequencyLimitDay(DEFAULT_FREQUENCY_LIMIT_DAY);
                warnFreqConfig.setFrequencyLimitHour(DEFAULT_FREQUENCY_LIMIT_HOUR);
                warnFreqConfig.setFrequencyLimitInterval(DEFAULT_FREQUENCY_LIMIT_INTERVAL);
            }
            warnConfigDTO = new AppWarnFreqConfigDTO();
            BeanUtils.copyProperties(warnFreqConfig, warnConfigDTO);
            warnConfigRedisDao.setWarnConfig(deptId, warnModuleType, type, ruleType, warnConfigDTO);
        }
        return warnConfigDTO;
    }
}
